#include"c3pom/application.h"
#include<omp.h>
#include<iostream>
#include<vector>
#include"c3pom/pluginmanager.h"
#include"c3pom/portalbufmanager.h"
#include"c3pom/portalmanager.h"
#include"c3pom/log.h"
using namespace std;
using namespace c3pom;
static Application* instance=NULL;
Application::Application()
{
	omp_init_lock(&envarLock);
	omp_init_lock(&cmdLock);
	envar["PORTAL_BUF_DIR"]="portalbufs";
	envar["PLUGIN_DIR"]="plugins";
	envar["LOG_FILE"]="c3pom.log";
	envar["RUNNING"]="true";
	envar["INIT_FINISHED"]="false";
	envar["PORTALBUFDIRLISTENING"]="true";
	envar["PLUGINDIRLISTENING"]="true";
	instance=this;
} 
void Application::init()
{
	regService(Log::getInstance());//日志服务

	//基本服务
	regService(PluginManager::getInstance());//插件管理服务
	regService(PortalBufManager::getInstance());//pb管理服务
	regService(PortalManager::getInstance());//portal管理服务
	//基本操作命令
	regCommand(new Env());
	regCommand(new Help());
	regCommand(new Svcm());
}
void Application::run()
{
	omp_set_nested(true);
#pragma omp parallel
	{
		omp_set_num_threads(services.size()+1);
#pragma omp single
		init();
		//一旦开始执行，默认就是并行状态，所有代码都将处于并行区管理之中，线程资源由openmp自行管理回收
		//并行启动各个基础服务
		for(map<string,Service*>::const_iterator map_it=services.begin();map_it!=services.end();map_it++)
		{
#pragma omp single nowait
			{
				Service* service=map_it->second;
				if(service!=NULL)
					map_it->second->run();
			}
		}
#pragma omp single 
		{
			//shell
			shell();
		}
	}
} 

Application* Application::getInstance()
{
	if(instance==NULL)
		instance=new Application();
	return instance;
}

void Application::regCommand(Command* cmd)
{
	commands[cmd->name()]=cmd;
} 
void Application::regService(Service* service)
{
	services[service->name()]=service;
}

void Application::shell()
{
	while(envar["RUNNING"]=="true")
	{
		cout<<"c3pom->";
		string cmdline;
		vector<string> args;//参数列表
		getline(cin,cmdline);
		if(cmdline.length()<2)
			continue;
		int loc;
		do
		{
			string arg="";
			loc=cmdline.find(" ");
			if(-1==loc)//最后一段
			{
				arg=cmdline.substr(0,cmdline.length());
				args.push_back(arg);
				break;
			}
			//中间
			arg=cmdline.substr(0,loc);
			cmdline.erase(0,loc+1);
			args.push_back(arg);
		}while(true);
		if(commands.count(args[0])>0)
		{
			if(args.size()>1&&args[args.size()-1]=="&")//2个以上，并以&结尾
			{
#pragma omp parallel num_threads(2)
				{
					if(omp_get_thread_num()>0)
						commands[args[0]]->exec(args);
					else
						shell();
				}
			}
			else
			{
				commands[args[0]]->exec(args);
			}
		}
		else
		{
			cout<<"unknown command:"<<args[0]<<endl;
		} 
		args.clear();
	}
}
int Application::Svcm::exec(vector<string>)
{
	cout<<"service list"<<endl;
	cout<<"name\t\t\tdesc\t"<<endl;
	map<string,Service*>::const_iterator map_it=Application::getInstance()->services.begin();
	for(;map_it!=Application::getInstance()->services.end();map_it++)
	{
		cout<<map_it->first<<"\t\t"<<map_it->second->desc()<<endl;
	}
	return 0;
}
int Application::Env::exec(vector<string>)
{
	map<string,string>::const_iterator map_it=Application::getInstance()->envar.begin();
	for(;map_it!=Application::getInstance()->envar.end();map_it++)
	{
		cout<<map_it->first<<"="<<map_it->second<<endl;
	}
	return 0;
}
int Application::Help::exec(vector<string>)
{
	map<string,Command*>::const_iterator map_it=Application::getInstance()->commands.begin(); 	
	for(;map_it!=Application::getInstance()->commands.end();map_it++)
	{
		Command* cmd=map_it->second;
		string desc;
		if(cmd!=NULL)
			desc=cmd->desc();
		cout<<map_it->first<<":"<<desc<<endl;
	}
	return 0;
}

string Application::Svcm::name()
{
	return "svcm";
}
string Application::Env::name()
{
	return "env";
}
string Application::Help::name()
{
	return "help";
}

string Application::Svcm::desc()
{
	return "运行中的基本服务";
}
string Application::Env::desc()
{
	return "环境变量";
}
string Application::Help::desc()
{
	return "帮助";
}
